package repository

import (
	"context"
	"gorm.io/gorm"
	"onvif_server/internal/model"
)

type CameraRepository interface {
	List(ctx context.Context, kw string, scopesFn ...func(*gorm.DB) *gorm.DB) (total int64, res []*model.Camera, err error)
	All(ctx context.Context) (res []*model.Camera, err error)
	Create(ctx context.Context, m *model.Camera) error
	Update(ctx context.Context, m *model.Camera, fields ...string) error
	GetByID(ctx context.Context, id int) (*model.Camera, error)
	GetByIDs(ctx context.Context, ids []int) ([]*model.Camera, error)
	GetByDeviceId(ctx context.Context, deviceId string) (*model.Camera, error)
	GetByDeviceIds(ctx context.Context, deviceIds []string) ([]*model.Camera, error)
	DeleteByIDs(ctx context.Context, id []int) error
}

func NewCameraRepository(r *Repository) CameraRepository {
	return &cameraRepository{
		Repository: r,
	}
}

type cameraRepository struct {
	*Repository
}

func (r *cameraRepository) Create(ctx context.Context, m *model.Camera) error {
	return r.DB(ctx).Create(m).Error
}

func (r *cameraRepository) Update(ctx context.Context, m *model.Camera, fields ...string) error {
	_db := r.DB(ctx)
	if len(fields) > 0 {
		_db = _db.Select(fields)
	}
	return _db.Updates(m).Error
}

func (r *cameraRepository) GetByID(ctx context.Context, id int) (m *model.Camera, err error) {
	err = r.DB(ctx).Where("id = ?", id).First(&m).Error
	return
}

func (r *cameraRepository) GetByDeviceId(ctx context.Context, deviceId string) (m *model.Camera, err error) {
	err = r.DB(ctx).Where("device_id = ?", deviceId).First(&m).Error
	return
}

func (r *cameraRepository) DeleteByIDs(ctx context.Context, id []int) error {
	return r.DB(ctx).Delete(&model.Camera{}, id).Error
}

// List 获取列表
func (r *cameraRepository) List(ctx context.Context, kw string, scopesFn ...func(*gorm.DB) *gorm.DB) (total int64, res []*model.Camera, err error) {
	db := r.DB(ctx).Model(&model.Camera{})
	if kw != "" {
		_k := "%" + kw + "%"
		db.Where("alias like ? ", _k)
	}
	err = db.Count(&total).Error
	if err != nil || total == 0 {
		return
	}
	err = db.Scopes(scopesFn...).Find(&res).Error
	return
}

// All
func (r *cameraRepository) All(ctx context.Context) (res []*model.Camera, err error) {
	err = r.DB(ctx).Model(&model.Camera{}).Find(&res).Error
	return
}

func (r *cameraRepository) GetByIDs(ctx context.Context, ids []int) (ms []*model.Camera, err error) {
	if len(ids) == 0 {
		return make([]*model.Camera, 0), nil
	}
	err = r.DB(ctx).Where("id in ?", ids).Find(&ms).Error
	return
}

func (r *cameraRepository) GetByDeviceIds(ctx context.Context, deviceIds []string) (ms []*model.Camera, err error) {
	if len(deviceIds) == 0 {
		return make([]*model.Camera, 0), nil
	}
	err = r.DB(ctx).Where("device_id in ?", deviceIds).Find(&ms).Error
	return
}
